package com.leetcode.testcode;

import org.springframework.beans.factory.FactoryBean;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author yanglin
 * @create 2024-01-23 16:45 星期二
 * description:
 */
public class SwitchPrint {

    /**
     * 线程、操作、资源类
     * 判断、通知、去干活
     *  相对于if，while能够解决虚假唤醒问题
     * 
     */
    
    public static void main(String[] args) throws InterruptedException {
        SwitchPrint switchPrint = new SwitchPrint();
        
//        new Thread(() -> {
//            for (int i = 0; i < 10; i++) {
//                try {
//                    switchPrint.printNum();
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
//        }).start();
//        
//        new Thread(() -> {
//            for (int i = 0; i < 10; i++) {
//                try {
//                    switchPrint.printChar();
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
//        }).start();
        
        new Thread(() -> {
            try {
                switchPrint.printNum2();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"A").start();
        
        
        new Thread(() -> {
            try {
                switchPrint.printChar2();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"B").start();
        
        Thread.sleep(2000000);
    }

    //控制打印顺序
    public boolean flag = true;

    private Integer i = 0;
    private char c = 'a';
    
    /**
     * 打印数字
     */
    public void printNum() throws InterruptedException {
        synchronized (this){
            while(!flag){   //只判断不做事的情况
                this.wait();
            }
            System.out.println(i++);
            this.flag = false;
            this.notifyAll();
        }
    }


    /**
     * 打印字母
     */
    public void printChar() throws InterruptedException {
        synchronized (this){
            while (flag){
                this.wait();
            }
            System.out.println(c++);
            this.flag = true;
            this.notifyAll();
        }
        
    }
    
    Lock lock = new ReentrantLock();
    Condition printNum = lock.newCondition();
    Condition printChar = lock.newCondition();
    
    public void printNum2() throws InterruptedException {
        lock.lock();
        for (int j = 0; j < 10; j++) {
            while (!flag){
                printNum.await();   //等待
            }
            System.out.println(i++);
            flag = false;
            printChar.signalAll();     //唤醒
        }
        lock.unlock();
    }
    
    public void printChar2() throws InterruptedException {
        lock.lock();
        for (int j = 0; j < 10; j++) {
            while (flag){
                printChar.await();  //等待
            }
            System.out.println(c++);
            flag = true;
            printNum.signalAll();     //唤醒
        }
        lock.unlock();
    }

}
